/*
 * Copyright (C), 2002-2016, 上海亦寻信息技术有限公司
 * FileName: SignedServiceImp.java
 * Author:   linyao
 * Date:     2016-7-2 上午10:57:35
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.emm.yixun.website.service.signed;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.ProcessInstanceHistoryLog;
import org.activiti.engine.task.Comment;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.emm.yixun.common.model.HaveReceiveRefund;
import com.emm.yixun.common.model.NeedReceiveRefund;
import com.emm.yixun.common.model.TransactionRelation;
import com.emm.yixun.common.model.User;
import com.emm.yixun.common.model.dto.HaveReceiveRefundDto;
import com.emm.yixun.common.model.dto.NeedReceiveRefundDto;
import com.emm.yixun.common.model.dto.SignedDto;
import com.emm.yixun.common.model.dto.TransactionRelationDto;
import com.emm.yixun.common.model.dto.UserDto;
import com.emm.yixun.common.model.enums.AuditStatusEnum;
import com.emm.yixun.common.model.enums.BusinessStatusEnum;
import com.emm.yixun.common.model.enums.BusinessTypeEnum;
import com.emm.yixun.common.model.enums.DelFlagEnum;
import com.emm.yixun.common.model.enums.DocTypeEnum;
import com.emm.yixun.common.model.enums.NeedStatusEnum;
import com.emm.yixun.common.model.enums.PaymentMethodEnum;
import com.emm.yixun.common.model.enums.ReceivablesTypeEnum;
import com.emm.yixun.common.model.enums.RelationTypeEnum;
import com.emm.yixun.common.model.enums.SignedBusinessStatusEnum;
import com.emm.yixun.common.page.Page;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.common.utils.DateStyle;
import com.emm.yixun.common.utils.DateUtils;
import com.emm.yixun.customer.service.SignedServiceFacade;
import com.emm.yixun.customer.service.TransactionRelationServiceFacade;
import com.emm.yixun.marketing.service.HaveReceiveRefundServiceFacade;
import com.emm.yixun.marketing.service.NeedReceiveRefundServiceFacade;
import com.emm.yixun.system.service.UserServiceFacade;
import com.emm.yixun.website.vo.process.HistoryTaskInfoVo;

/**
 * 〈一句话功能简述〉 〈功能详细描述〉
 * 
 * @author linyao
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class SignedServiceImp implements SignedService {
	@Autowired
	private SignedServiceFacade signedServiceFacade;
	@Autowired
	private HistoryService historyService;
	@Autowired
	private TaskService taskService;
	@Autowired
	private UserServiceFacade userServiceFacade;
	@Autowired
	private HaveReceiveRefundServiceFacade haveReceiveRefundServiceFacade;
	@Autowired
	private NeedReceiveRefundServiceFacade needReceiveRefundServiceFacade;
	@Autowired
	private TransactionRelationServiceFacade transactionRelationServiceFacade;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.emm.yixun.website.service.signed.SignedService#getSignedDtoList(com.emm.yixun.common.model.dto.SignedDto,
	 * java.lang.Integer, java.lang.Integer)
	 */
	public SignedDto setSignedQueryDto(SignedDto reqDto){
		if (StringUtils.isNotBlank(reqDto.getM_auditStatus())) {
			String sql = new String(" and t.audit_status in (");
			String[] audits = reqDto.getM_auditStatus().split(",");
			String sbsql = "";
			for (int i = 0; i < audits.length; i++) {
				sbsql += audits[i];
				if (i != audits.length - 1) {
					sbsql += ",";
				}
			}
			sql += sbsql + ")";
			reqDto.setM_auditStatus(sql);
		}
		if (StringUtils.isNotBlank(reqDto.getM_businessStatus())) {
			String sql = new String(" and t.business_status in (");
			String[] status = reqDto.getM_businessStatus().split(",");
			String sbsql = "";
			for (int i = 0; i < status.length; i++) {
				sbsql += status[i];
				if (i != status.length - 1) {
					sbsql += ",";
				}
			}
			sql += sbsql + ")";
			reqDto.setM_businessStatus(sql);
		}
		return reqDto;
	}
	
	public List<SignedDto> setSignedListDto(List<SignedDto> list){
		if(list!=null&&list.size()>0){
			for (SignedDto signedDto : list) {
				//查询成交人
				//signedDto.setUserName(userName(signedDto.getId()));
				
				//合同总金额
				BigDecimal totalSignedAmount = signedDto.getSignAmount();
				if(signedDto.getDecorationMoney() != null) {
					totalSignedAmount = signedDto.getSignAmount().add(signedDto.getDecorationMoney());
				}
				signedDto.setTotalSignedAmount(totalSignedAmount);
				//计算未收款 = 合同金额-已收的全部已收款
				if(signedDto.getSignAmount() != null){
					BigDecimal receivables = new BigDecimal("0");
					if(signedDto.getTotalRealAmount() != null){
						receivables = totalSignedAmount.subtract(signedDto.getTotalRealAmount());
					}else{
						receivables = totalSignedAmount;
					}
					signedDto.setReceivables(receivables);
				}
				
				//当有逾期天数时，进行逾期未收款计算
				if(StringUtils.isNotBlank(signedDto.getOverdueDay())){
					if(Integer.parseInt(signedDto.getOverdueDay()) <= 0){
						continue;
					}
				}else{
					continue;
				}
				
				//计算逾期未付款 = 逾期的款项的应收款-已收款 之和  （同一个合同多项逾期未付款时，逾期款=所有逾期金额之和）
				BigDecimal needAmount = new BigDecimal("0"); //逾期的款项的应收款总和
				BigDecimal haveAmount = new BigDecimal("0"); //逾期的款项的已收款总和
				NeedReceiveRefundDto needDto = new NeedReceiveRefundDto();
				needDto.setRelationId(signedDto.getId());
				needDto.setReceivablesDateAfter(Calendar.getInstance().getTime());
				needDto.setStatus(NeedStatusEnum.NO.getNo());
				needDto.setBusinessType(BusinessTypeEnum.SIGNED.getNo());
				needDto.setDocType(DocTypeEnum.COLLECTION.getNo());
				needDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
				ResponseList<NeedReceiveRefund> needRes = needReceiveRefundServiceFacade.findByDto(needDto);
				if(needRes.isSuccess() && needRes.getEntity() != null){
					for(NeedReceiveRefund need : needRes.getEntity()){
						needAmount = needAmount.add(need.getTotalReceivablesAmount());
						haveAmount = haveAmount.add(haveAmount(need));
					}
				}
				BigDecimal overdueAmount = needAmount.subtract(haveAmount);
				signedDto.setOverdueAmount(overdueAmount);
			}
		}
		return list;
	}
	@Override
	public Response<Page<SignedDto>> getSignedDtoList(SignedDto reqDto, Integer pageSize, Integer pageNum) {
		reqDto = setSignedQueryDto(reqDto);
		Response<Page<SignedDto>> response = signedServiceFacade.getSignedDtoList(reqDto, pageSize, pageNum);
		if (reqDto.getCustomerId() != null && response.isSuccess() && response.getEntity() != null
				&& response.getEntity().getRows() != null && response.getEntity().getRows().size() > 0) {// 查询审批历史记录
			List<SignedDto> list = response.getEntity().getRows();
			for (SignedDto signedDto : list) {
				if (signedDto.getProcInstId() != null) {
					List<HistoricActivityInstance> instances = historyService.createHistoricActivityInstanceQuery()
							.processInstanceId(signedDto.getProcInstId()).orderByHistoricActivityInstanceStartTime()
							.desc().list();
					if (instances != null && instances.size() > 0) {
						List<HistoryTaskInfoVo> userTaskList = new ArrayList<HistoryTaskInfoVo>();
						boolean isEnd = true;
						for (HistoricActivityInstance historicActivityInstance : instances) {
							if (historicActivityInstance.getEndTime() != null) {// 过滤未审批的数据
								HistoryTaskInfoVo htf = new HistoryTaskInfoVo();

								if (historicActivityInstance.getActivityType().equals("startEvent")) {// 开始节点
									ProcessInstanceHistoryLog processInstanceHistoryLog = historyService
											.createProcessInstanceHistoryLogQuery(
													historicActivityInstance.getProcessInstanceId()).singleResult();
									htf.setTaskName("启动");
									UserDto ud=new UserDto();
									ud.setUserAccount(processInstanceHistoryLog.getStartUserId());
									ResponseList<User> userList=userServiceFacade.findByDto(ud);
									if(userList.isSuccess() && null!=userList.getEntity()){
										htf.setTaskUserName(userList.getEntity().get(0).getUserName());
									}
									htf.setTaskCheckStatus("发起");
									htf.setStartDate(historicActivityInstance.getStartTime());
									htf.setEndDate(historicActivityInstance.getEndTime());

									userTaskList.add(htf);
									continue;
								}

								if (historicActivityInstance.getActivityType().equals("endEvent")) {// 结束节点
									continue;
								}

								List<Comment> commentList = taskService.getTaskComments(historicActivityInstance
										.getTaskId());
								htf.setTaskName(historicActivityInstance.getActivityName());
								htf.setStartDate(historicActivityInstance.getStartTime());
								htf.setEndDate(historicActivityInstance.getEndTime());
								if (isEnd)// 为最后一个审批节点
									htf.setIsEnd(isEnd);
								if (null != commentList && commentList.size() > 0){
									String userAccount=commentList.get(0).getUserId();
									UserDto ud=new UserDto();
									ud.setUserAccount(userAccount);
									ResponseList<User> userList=userServiceFacade.findByDto(ud);
									if(userList.isSuccess() && null!=userList.getEntity()){
										htf.setTaskUserName(userList.getEntity().get(0).getUserName());
									}
									
								}

								userTaskList.add(htf);

								isEnd = false;
							}
						}

						if (userTaskList.size() > 0) {
							for (HistoryTaskInfoVo historyTaskInfoVo : userTaskList) {
								if (historyTaskInfoVo.getTaskName().equals("启动")) {// 获取提交时间
									signedDto.setSmTartTime(historyTaskInfoVo.getStartDate());
								}
								if (historyTaskInfoVo.getIsEnd() != null && historyTaskInfoVo.getIsEnd()) {// 获取最后的审批人与审核时间
									signedDto.setTaskUserName(historyTaskInfoVo.getTaskUserName());
									signedDto.setCkEndTime(historyTaskInfoVo.getEndDate());
								}
							}
						}
					}
				}
			}
		}
		
		
		if (response.isSuccess() && response.getEntity() != null && response.getEntity().getRows() != null && response.getEntity().getRows().size() > 0) {
			List<SignedDto> list = response.getEntity().getRows();
			list=setSignedListDto(list);
			response.getEntity().setRows(list);
		}
		return response;
	}
	
	//查询成交人
	public String userName(long id){
		String userName = "";
		TransactionRelationDto dto = new TransactionRelationDto();
		dto.setBusinessId(id);
		dto.setRelationType(RelationTypeEnum.SIGNED.getNo());
		dto.setDelFlag(DelFlagEnum.UNDEL.getNo());
		ResponseList<TransactionRelation> trRes = transactionRelationServiceFacade.findByDto(dto);
		if(trRes.isSuccess() && trRes.getEntity() != null){
			for(TransactionRelation tr : trRes.getEntity()){
				Response<User> userRes = userServiceFacade.findById(tr.getRelationAgentid());
				if(userRes.isSuccess() && userRes.getEntity() != null){
					User user = userRes.getEntity();
					userName += user.getUserName() + ",";
				}
			}
		}
		if(StringUtils.isNotBlank(userName)){
			userName = userName.substring(0, userName.length()-1);
		}
		return userName;
	}
	
	
	//根据待收款ID，查询对应已收款
	public BigDecimal haveAmount(NeedReceiveRefund need){
		BigDecimal totalHaveAmount = new BigDecimal("0");
		HaveReceiveRefundDto dto = new HaveReceiveRefundDto();
		dto.setReceivablesId(need.getId());
		dto.setReceivablesType(ReceivablesTypeEnum.SIGNED.getNo());
		dto.setDocType(DocTypeEnum.COLLECTION.getNo());
		dto.setDelFlag(DelFlagEnum.UNDEL.getNo());
		ResponseList<HaveReceiveRefund> haveRes = haveReceiveRefundServiceFacade.findByDto(dto);
		if(haveRes.isSuccess() && haveRes.getEntity() != null){
			for(HaveReceiveRefund have : haveRes.getEntity()){
				totalHaveAmount = totalHaveAmount.add(have.getRealAmount());
			}
		}
		return totalHaveAmount;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.emm.yixun.website.service.signed.SignedService#selectSignedDtoList(com.emm.yixun.common.model.dto.SignedDto,
	 * java.lang.Integer, java.lang.Integer)
	 */
	@Override
	public Response<Page<SignedDto>> selectSignedDtoList(SignedDto reqDto, Integer pageSize, Integer pageNum) {
		if (StringUtils.isNotBlank(reqDto.getM_auditStatus())) {
			String sql = new String(" and dtra.audit_status in (");
			String[] audits = reqDto.getM_auditStatus().split(",");
			String sbsql = "";
			for (int i = 0; i < audits.length; i++) {
				sbsql += audits[i];
				if (i != audits.length - 1) {
					sbsql += ",";
				}
			}
			sql += sbsql + ")";
			reqDto.setM_auditStatus(sql);
		}
		Response<Page<SignedDto>> response = signedServiceFacade.selectSignedDtoList(reqDto, pageSize, pageNum);

		return response;
	}
	
	@Override
	public ResponseList<SignedDto> selectAllDto(SignedDto reqDto) {
		if (StringUtils.isNotBlank(reqDto.getM_auditStatus())) {
			String sql = new String(" and dtra.audit_status in (");
			String[] audits = reqDto.getM_auditStatus().split(",");
			String sbsql = "";
			for (int i = 0; i < audits.length; i++) {
				sbsql += audits[i];
				if (i != audits.length - 1) {
					sbsql += ",";
				}
			}
			sql += sbsql + ")";
			reqDto.setM_auditStatus(sql);
		}
		ResponseList<SignedDto> response = signedServiceFacade.selectAllDto(reqDto);

		return response;
	}
	
	@Override
	public ResponseList<SignedDto> allDto(SignedDto reqDto) {
		ResponseList<SignedDto> response = signedServiceFacade.allDto(reqDto);

		return response;
	}

	@Override
	public List<SignedDto> querySignedDtoExport(SignedDto reqDto) {
		reqDto=setSignedQueryDto(reqDto);
		ResponseList<SignedDto> signedList = signedServiceFacade.querySignedDtoExport(reqDto);
		if(signedList.getEntity()!=null){
			List<SignedDto> list = signedList.getEntity();
			list = setSignedListDto(list);
			return list;
		}
		return null;
	}

	@Override
	public List<Map<String, String>> returnFieldSigned(List<SignedDto> list,String[] head) {
		List<Map<String, String>> listMap = new ArrayList<Map<String,String>>();
		for (int i=0;i<list.size();i++) {
			Map<String, String> map = new HashMap<String, String>();
			SignedDto signed = list.get(i);
			map.put(head[0]+"_"+i, DateUtils.DateToString(signed.getDidTime(), DateStyle.YYYY_MM_DD.getValue()));//签约日期
			map.put(head[1]+"_"+i, signed.getCustomerName());//签约日期
			map.put(head[2]+"_"+i, signed.getCombinedName()); //房号
			map.put(head[3]+"_"+i, signed.getHouseTypeName());//户型
			map.put(head[4]+"_"+i, signed.getCalculateArea()==null?"":signed.getCalculateArea().toString()); //计价面积
			map.put(head[5]+"_"+i, signed.getSignPrice()==null?"":signed.getSignPrice().toString()); //签约单价
			map.put(head[6]+"_"+i, signed.getSignAmount()==null?"":signed.getSignAmount().toString());//合同金额
			map.put(head[7]+"_"+i, signed.getPaymentMethod()==null?"":PaymentMethodEnum.getByNo(signed.getPaymentMethod()).getDes());//付款方式
			map.put(head[8]+"_"+i, signed.getReceivables()==null?"":signed.getReceivables().toString());//未收款
			map.put(head[9]+"_"+i, signed.getTotalRealAmount()==null?"0.00":signed.getTotalRealAmount().toString());//已收款
			String overDueDay =  signed.getOverdueDay();
			Integer overDue =  null;
			if(!StringUtils.isEmpty(overDueDay)){
				overDue = new Integer(overDueDay);
				if(overDue>0){
					overDueDay="是";
				}else{
					overDueDay = "否";
				}
			}else{
				overDueDay = "否";
			}
			map.put(head[10]+"_"+i, overDueDay==null?"":overDueDay);//是否逾期未付款
			map.put(head[11]+"_"+i, overDue==null||overDue<=0?"":overDue.toString()); //逾期天数
			map.put(head[12]+"_"+i, signed.getOverdueAmount()==null?"0.00":signed.getOverdueAmount().toString()); //逾期未付款金额
			map.put(head[13]+"_"+i, signed.getUserName()); //经纪人
			map.put(head[14]+"_"+i, signed.getBusinessStatus()==null?"":SignedBusinessStatusEnum.getByNo(signed.getBusinessStatus()).getDes());  //业务状态
			map.put(head[15]+"_"+i, signed.getAuditStatus()==null?"":AuditStatusEnum.getByNo(signed.getAuditStatus()).getDes()); //审核状态
			listMap.add(map);
		}
		return listMap;
	}

	@Override
	public Response<Page<SignedDto>> getPageDtoByCustomerId(String customerId, Integer pageSize, Integer pageNum) {
		Response<Page<SignedDto>> response = signedServiceFacade.getPageDtoByCustomerId(customerId, pageSize, pageNum);
		if (response.isSuccess() && response.getEntity() != null && response.getEntity().getRows() != null 
				&& response.getEntity().getRows().size() > 0) {// 查询审批历史记录
			List<SignedDto> list = response.getEntity().getRows();
			for (SignedDto signedDto : list) {
				if (signedDto.getProcInstId() != null) {
					List<HistoricActivityInstance> instances = historyService.createHistoricActivityInstanceQuery()
							.processInstanceId(signedDto.getProcInstId()).orderByHistoricActivityInstanceStartTime()
							.desc().list();
					if (instances != null && instances.size() > 0) {
						List<HistoryTaskInfoVo> userTaskList = new ArrayList<HistoryTaskInfoVo>();
						boolean isEnd = true;
						for (HistoricActivityInstance historicActivityInstance : instances) {
							if (historicActivityInstance.getEndTime() != null) {// 过滤未审批的数据
								HistoryTaskInfoVo htf = new HistoryTaskInfoVo();
								if (historicActivityInstance.getActivityType().equals("startEvent")) {// 开始节点
									ProcessInstanceHistoryLog processInstanceHistoryLog = historyService
											.createProcessInstanceHistoryLogQuery(
													historicActivityInstance.getProcessInstanceId()).singleResult();
									htf.setTaskName("启动");
									UserDto ud=new UserDto();
									ud.setUserAccount(processInstanceHistoryLog.getStartUserId());
									ResponseList<User> userList=userServiceFacade.findByDto(ud);
									if(userList.isSuccess() && null!=userList.getEntity()){
										htf.setTaskUserName(userList.getEntity().get(0).getUserName());
									}
									htf.setTaskCheckStatus("发起");
									htf.setStartDate(historicActivityInstance.getStartTime());
									htf.setEndDate(historicActivityInstance.getEndTime());

									userTaskList.add(htf);
									continue;
								}
								if (historicActivityInstance.getActivityType().equals("endEvent")) {// 结束节点
									continue;
								}
								List<Comment> commentList = taskService.getTaskComments(historicActivityInstance
										.getTaskId());
								htf.setTaskName(historicActivityInstance.getActivityName());
								htf.setStartDate(historicActivityInstance.getStartTime());
								htf.setEndDate(historicActivityInstance.getEndTime());
								if (isEnd)// 为最后一个审批节点
									htf.setIsEnd(isEnd);
								if (null != commentList && commentList.size() > 0){
									String userAccount=commentList.get(0).getUserId();
									UserDto ud=new UserDto();
									ud.setUserAccount(userAccount);
									ResponseList<User> userList=userServiceFacade.findByDto(ud);
									if(userList.isSuccess() && null!=userList.getEntity()){
										htf.setTaskUserName(userList.getEntity().get(0).getUserName());
									}
								}
								userTaskList.add(htf);
								isEnd = false;
							}
						}
						if (userTaskList.size() > 0) {
							for (HistoryTaskInfoVo historyTaskInfoVo : userTaskList) {
								if (historyTaskInfoVo.getTaskName().equals("启动")) {// 获取提交时间
									signedDto.setSmTartTime(historyTaskInfoVo.getStartDate());
								}
								if (historyTaskInfoVo.getIsEnd() != null && historyTaskInfoVo.getIsEnd()) {// 获取最后的审批人与审核时间
									signedDto.setTaskUserName(historyTaskInfoVo.getTaskUserName());
									signedDto.setCkEndTime(historyTaskInfoVo.getEndDate());
								}
							}
						}
					}
				}
				
				if((BusinessStatusEnum.SIGNED.getNo().equals(signedDto.getBusinessStatus())
						|| BusinessStatusEnum.RENAMED.getNo().equals(signedDto.getBusinessStatus()))
						&& BusinessStatusEnum.CHECKWARDS.getNo().equals(signedDto.getBusinessSecStatus())) {
					signedDto.setM_businessStatus("退房");
				}else if((BusinessStatusEnum.SIGNED.getNo().equals(signedDto.getBusinessStatus())
						|| BusinessStatusEnum.RENAMED.getNo().equals(signedDto.getBusinessStatus()))
						&& BusinessStatusEnum.HAVEWARDS.getNo().equals(signedDto.getBusinessSecStatus())) {
					signedDto.setM_businessStatus("换房");
				}else if(BusinessStatusEnum.SIGNED.getNo().equals(signedDto.getBusinessStatus())
						&& StringUtils.isBlank(signedDto.getBusinessSecStatus())) {
					signedDto.setM_businessStatus("签约");
				}else if(BusinessStatusEnum.RENAMED.getNo().equals(signedDto.getBusinessStatus())
						&& StringUtils.isBlank(signedDto.getBusinessSecStatus())) {
					signedDto.setM_businessStatus("更名");
				}
			}
		}
		
		if (response.isSuccess() && response.getEntity() != null && response.getEntity().getRows() != null && response.getEntity().getRows().size() > 0) {
			List<SignedDto> list = response.getEntity().getRows();
			list=setSignedListDto(list);
			response.getEntity().setRows(list);
		}
		return response;
	}
}
